//+FHDR-------------------------------------------------------------------------
//            __     __ __                  ____     ___ ___
//           |  |   |  /__| ____ ___ ___   /    \   /  ____/
//           |  \___/  |  /   __    __   \/  __  \ /  /
//           |   ___   |  |  /  \  /  \     /__\  (  <
//           |  /   \  |  |  |  |  |  |    /    \     \____
//           |__|   |__ __ __|  |__|  |___/      \__ __ ___\ 2.0                     
//------------------------------------------------------------------------------
//-- Module Name     :    frame_process
//-- Hierarchy       :    hiamc顶层 - * - frame_process
//-- Description     :    分组处理顶层                                             
//                                                                              
//-- Last Modified   : 2013-02-26 15:31
//-- Revision history:                                                          
//     Date               Author       Description                              
//     2012-12-24 17:08   Tiger          Initialize code
//     2012-01-02         Tiger          加入注释
//-FHDR-------------------------------------------------------------------------
/***************************************************************/
//  本模块复位统一为异步低电平有效复位。
//  100G SDN项目，将所有的fifo全部改写为首字置出的fifo，减少缓存浪费的时间
/***************************************************************/
//调度模块在总线搬移时执行修改、删除或者增加等操作
`timescale 1ns/100ps

module frame_process(
                     input wire clk,
                     input wire rst_n,
                     input wire [9:0]ram_2p_cfg_register,
		     input wire [6:0] rf_2p_cfg_register ,
                     // output wire rd_rdy,
                     //与mac或拆帧模块接口,统一以mac结尾
                     output wire rx_rdy_mac,   
                     input wire rx_ff_sop_mac,
                     input wire rx_ff_eop_mac,
                     input wire rx_ff_dval_mac,
                     input wire rx_ff_dsav_mac,               //
                     input wire [255:0] rx_ff_data_mac,
                     input wire [4:0] rx_ff_mod_mac,
                     //input wire rx_ff_err_mac,                   //*暂时无用
                     input wire [7:0] src_node_id_i_mac,
                     

                     //与插入模块接口，统一以insert结尾
                     output wire rx_rdy_insert,
                     input wire rx_ff_sop_insert,
                     input wire rx_ff_eop_insert,
                     input wire rx_ff_dval_insert,
                     input wire rx_ff_dsav_insert,
                     input wire [255:0] rx_ff_data_insert,
                     input wire [4:0] rx_ff_mod_insert,
                     input wire insert_empty,                       
                     // input wire is_insert_frame_insert,          //插入帧标志
                     input wire [7:0] des_node_id_insert, //插入帧目的节点号
                     input wire [2:0] pri_insert_i,

                     //和调度器之间的接口
                     //和frame_info_fifo的接口 ,和调度器有关的接口
                     output wire frame_info_fifo_empty,
                     input  wire frame_info_fifo_rden,
                     output wire[31:0] frame_info_fifo_o,
                     
                     input wire mem_que_rdy,
                     //add by Hbing 8-10
                     output wire in_buf_val,   //调度信息有效信号
                     output wire multicast,  //组播帧
                     input  wire schedule_start,  //调度模块的应答信号，表示以上帧信息已经被接收，维持一周期高电平

                     output wire [ 7:0] src_node_id,
                     output wire [47:0] mac_des_addr,
                     output wire [47:0] mac_src_addr,  //MAC地址用来查找单播表
                     output wire [128:0] ip_src_addr,
                     output wire [128:0] ip_des_addr,  //是否需要支持IGMP V3源地址过滤？ 

                     input  wire access_fail,
                     output wire in_buf_access_fail,
                     //流分类接口
                     input wire action_dval,               //流分类输出使能
                     input wire [88:0] action_data,        //流分类操作码
                     input wire [ 8:0] layend,
                     //与总线的接口
                     output wire trans_ready,
                     input wire trans_start,                       //总线给出的总线数据通路可用信号
		     input wire discard_start,
                     output wire frame_rd_end,
                     output wire [262:0] bus_data_o,

                     output wire bus_data_val_o,            //分组处理给出的数据有效信号
                     output wire bus_data_end_o,            //分组处理给出的总线数据搬移结束信号
                     output wire [10:0] frame_len_bus,
                     //与捕获模块的接口
                     input wire [15:0] eth_type,                //需要直接捕获到CPU的以太网帧类型
                     input wire capture_rdy,                    //捕获模块不忙信号
                     output wire [262:0] capture_data_o,     
                     output wire capture_dval,              //捕获写数据有效信号
                     
                     //zhangjy 2013.8.20
                     output wire  cpt_en,
                     output wire [10:0] cpt_frame_len
                    );
//数据fifo的接口
wire [262:0] fp_dpram_data;
wire fp_dpram_rden;

//指令码fifo接口,与流分类输出接口连接
wire action_data_rden     ;
wire [97:0] action_fifo_q ;
wire action_data_empty    ;
//和总线控制模块之间的信号
wire action_en;
wire [75:0]action_fifout;
wire action_fifout_rden;
wire [75:0]action_fifout_q;
// wire action_fifout_empty;

wire rx_rdy;
wire rd_rdy;
wire rx_ff_sop;
wire rx_ff_eop;
wire rx_ff_dval;
wire rx_ff_dsav;
wire [255:0] rx_ff_data;
wire [4:0] rx_ff_mod;
//wire rx_ff_err;               

wire is_insert_frame;
wire [7:0] insert_des_node_id;

wire des_node_wen;
wire [7:0] des_node_id;
wire des_node_ren;
wire [7:0] des_node_q;
//帧长信息frame_len_fifo相关接口
wire            fifo_wren;
wire            fifo_rden;
wire            fifo_full;
wire            fifo_empty;
wire    [10:0]  frame_length;
wire    [10:0]  frame_length_i;

//帧信息frame_info_fifo相关接口
wire            frame_info_fifo_wren;
wire            frame_info_fifo_full;
wire    [31:0]  frame_info_o;
wire    [ 2:0]  pri_insert_rx_i,pri_insert_fifo_i,pri_insert_fifo_o;
//add by Hbing--增加直接给定捕获帧类型的捕获方式
wire direct_capture;
wire direct_capture_q;
wire insert_fifo_empty;
wire insert_fifo_q;
wire insert_fifo_rden;
//源节点号
wire    [7:0]   src_node_id_i;

wire action_fifo_rden;
/***************************************************************/
//     输入时在插入和MAC接口间选择通路的选择器模块
/***************************************************************/
fp_input_path_switch U_fp_input_path_switch(
                                            .clk(clk),
                                            .rst_n(rst_n),

                                            //与rx_ctrl接口
                                            .rx_rdy(rx_rdy),                                        
                                            .rx_ff_sop(rx_ff_sop),
                                            .rx_ff_eop(rx_ff_eop),
                                            .rx_ff_dval(rx_ff_dval),
                                            .rx_ff_dsav(rx_ff_dsav),
                                            .rx_ff_data(rx_ff_data),
                                            .rx_ff_mod(rx_ff_mod),
                                            //.rx_ff_err(rx_ff_err),   
                                            .src_node_id_i(src_node_id_i),             //*
                                            .is_insert_frame(is_insert_frame),
                                            .insert_des_node_id(insert_des_node_id),
                                            .pri_insert_o(pri_insert_rx_i),
    
                                            //与mac或拆帧模块接口
                                            .rx_rdy_mac(rx_rdy_mac),
                                            .rx_ff_sop_mac(rx_ff_sop_mac),
                                            .rx_ff_eop_mac(rx_ff_eop_mac),
                                            .rx_ff_dval_mac(rx_ff_dval_mac),
                                            .rx_ff_dsav_mac(rx_ff_dsav_mac),
                                            .rx_ff_data_mac(rx_ff_data_mac),
                                            .rx_ff_mod_mac(rx_ff_mod_mac),
                                            //.rx_ff_err_mac(rx_ff_err_mac),                //*
                                            .src_node_id_i_mac(src_node_id_i_mac),
 
                                            //与插入模块接口
                                            .rx_rdy_insert(rx_rdy_insert),
                                            .rx_ff_sop_insert(rx_ff_sop_insert),
                                            .rx_ff_eop_insert(rx_ff_eop_insert),
                                            .rx_ff_dval_insert(rx_ff_dval_insert),
                                            .rx_ff_dsav_insert(rx_ff_dsav_insert),
                                            .rx_ff_data_insert(rx_ff_data_insert),
                                            .rx_ff_mod_insert(rx_ff_mod_insert),
                                            .insert_empty(insert_empty),
                                            .des_node_id_insert(des_node_id_insert),
                                            .pri_insert_i(pri_insert_i)
                                           );

//与CPU的接口   
//只存储了是否是插入帧的信息：1是 0不是 ，所有的帧都会存储         
  fifo_wxx_dxx_s #(
      .PTR(5),
      .WORDS(32),
      .W_SIZE(1),
      .A_FULL(31)
    ) inst_insert_fifo (
      .clock         (clk),
      .rst_n         (rst_n),
      .fifo_wen      (rx_ff_sop),
      .fifo_wdata    (is_insert_frame),
      .fifo_ren      (insert_fifo_rden),
      .fifo_rdata    (insert_fifo_q),
      .fifo_empty_rd (insert_fifo_empty),
      .almost_full   (/*almost_full*/)
    );

/***************************************************************/
//                      数据接收和存储管理部分
/***************************************************************/
fp_rx_ctrl U_fp_rx_ctrl(
                        .clk(clk),
                        .rst_n(rst_n),
                        .ram_2p_cfg_register(ram_2p_cfg_register),
			.rf_2p_cfg_register (rf_2p_cfg_register),
                        .mem_que_rdy(mem_que_rdy),

                        //数据输入接口
                        .rx_rdy(rx_rdy),
                        .rd_rdy(rd_rdy),
                        .rx_ff_sop(rx_ff_sop),
                        .rx_ff_eop(rx_ff_eop),
                        .rx_ff_dval(rx_ff_dval),
                        //.rx_ff_dsav(rx_ff_dsav),
                        .rx_ff_data(rx_ff_data),
                        .rx_ff_mod(rx_ff_mod),
                        //.rx_ff_err(rx_ff_err), 
                        .src_node_id_i(src_node_id_i),                       

                        .insert_frame_flag(is_insert_frame),
                        .insert_des_node_id(insert_des_node_id),
                        .pri_insert_i(pri_insert_rx_i),
                        
                        //读RAM接口，交给总线控制模块 
                        .fp_dpram_data(fp_dpram_data),
                        .fp_dpram_rden(fp_dpram_rden),   
                        // add by Hbing 8-10
                        .src_node_id(src_node_id),
                        .mac_des_addr(mac_des_addr),
                        .mac_src_addr(mac_src_addr),
                        .ip_src_addr(ip_src_addr),
                        .ip_des_addr(ip_des_addr),
                        .multicast(multicast),
                        
                        .eth_type(eth_type),
                        .direct_capture(direct_capture),
                        
                        .schedule_start(schedule_start),
                        .in_buf_val(in_buf_val),  

                        .access_fail(access_fail),
                        .in_buf_access_fail(in_buf_access_fail),          

                        //接收到的帧同时写入帧长信息的fifo和bus_ctrl中的模块
                        .fifo_full(fifo_full),
                        .fifo_wren(fifo_wren),
                        .frame_length(frame_length),

                        //将插入帧的目的节点号存储
                        .des_node_wen(des_node_wen),
                        .des_node_id(des_node_id),
                        .pri_insert_o(pri_insert_fifo_i)                 
                       );

//des_node_fifo中存储目的节点号
  fifo_wxx_dxx_s #(
      .PTR(5),
      .WORDS(32),
      .W_SIZE(8),
      .A_FULL(31)
    ) inst_des_node_fifo (
      .clock         (clk),
      .rst_n         (rst_n),
      .fifo_wen      (des_node_wen),
      .fifo_wdata    (des_node_id),
      .fifo_ren      (des_node_ren),
      .fifo_rdata    (des_node_q),
      .fifo_empty_rd (/*fifo_empty_rd*/),
      .almost_full   (/*almost_full*/)
    );

//pri_insert_fifo中存储插入帧的优先级信息
  fifo_wxx_dxx_s #(
      .PTR(5),
      .WORDS(32),
      .W_SIZE(3),
      .A_FULL(31)
    ) inst_pri_insert_fifo (
      .clock         (clk),
      .rst_n         (rst_n),
      .fifo_wen      (des_node_wen),
      .fifo_wdata    (pri_insert_fifo_i),
      .fifo_ren      (des_node_ren),
      .fifo_rdata    (pri_insert_fifo_o),
      .fifo_empty_rd (/*fifo_empty_rd*/),
      .almost_full   (/*almost_full*/)
    );
//直接捕获至CPU的数据帧
  fifo_wxx_dxx_s #(
          .PTR(5),
          .WORDS(32),
          .W_SIZE(1),
          .A_FULL(31)
      ) U_directcap_fifo (
          .clock         (clk),
          .rst_n         (rst_n),
          .fifo_wen      (rx_ff_eop),
          .fifo_wdata    (direct_capture),
          .fifo_ren      (action_fifo_rden),
          .fifo_rdata    (direct_capture_q),
          .fifo_empty_rd (/*fifo_empty_rd*/),
          .almost_full   (/*almost_full*/)
      );
/***************************************************************/
//     流分类输出指令码给分组处理的指令码数据fifo
/***************************************************************/
  fifo_wxx_dxx_s #(
      .PTR(5),
      .WORDS(32),
      .W_SIZE(89+9),
      .A_FULL(31)
    ) inst_actiondata_fifo (
      .clock         (clk),
      .rst_n         (rst_n),
      .fifo_wen      (action_dval),
      .fifo_wdata    ({layend, action_data}),
      .fifo_ren      (action_data_rden),
      .fifo_rdata    (action_fifo_q),
      .fifo_empty_rd (action_data_empty),
      .almost_full   (/*almost_full*/)
    );

/***************************************************************/
//     帧提取模块提取的帧长信息，存储到frame_len_fifo
/***************************************************************/
  fifo_wxx_dxx_s #(
      .PTR(5),
      .WORDS(32),
      .W_SIZE(11),
      .A_FULL(31)
    ) inst_frame_len_fifo (
      .clock         (clk),
      .rst_n         (rst_n),
      .fifo_wen      (fifo_wren),
      .fifo_wdata    (frame_length),
      .fifo_ren      (fifo_rden),
      .fifo_rdata    (frame_length_i),
      .fifo_empty_rd (fifo_empty),
      .almost_full   (fifo_full)
    );

/***************************************************************/
//     帧信息存储到frame_info_fifo，供调度模块读取
/***************************************************************/        
  fifo_wxx_dxx_s #(
      .PTR(5),
      .WORDS(32),
      .W_SIZE(32),
      .A_FULL(31)
    ) inst_frame_info_fifo (
      .clock         (clk),
      .rst_n         (rst_n),
      .fifo_wen      (frame_info_fifo_wren),
      .fifo_wdata    (frame_info_o),
      .fifo_ren      (frame_info_fifo_rden),
      .fifo_rdata    (frame_info_fifo_o),
      .fifo_empty_rd (frame_info_fifo_empty),
      .almost_full   (frame_info_fifo_full)
    );

/***************************************************************/
//                      指令码处理模块
/***************************************************************/
fp_action_exe U_fp_action_exe(
                              .clk(clk),
                              .rst_n(rst_n), 
                              
                              //指令码输入fifo接口
                              .action_fifo_q(action_fifo_q),
                              .action_data_rden(action_data_rden),
                              .action_data_empty(action_data_empty),

                              .frame_len_fifo_empty(fifo_empty),
                              .frame_len_fifo_rden(fifo_rden),
                              .frame_length_i(frame_length_i),

                              .direct_capture(direct_capture_q),
                              .action_fifo_rden(action_fifo_rden),
                              
                              //和调度器之间的接口
                              .frame_info_fifo_wren(frame_info_fifo_wren),
                              .frame_info_o(frame_info_o),
                              .frame_info_fifo_full(frame_info_fifo_full),
                              
                              //和总线控制模块之间的信号，写入对于的buf号中
                              .action_en(action_en),
                              .action_fifout(action_fifout),

                              .des_node_ren(des_node_ren),
                              .insert_dest_node(des_node_q),
    
                              .pri_insert(pri_insert_fifo_o),
                              .insert_fifo_empty(insert_fifo_empty),
                              .insert_fifo_q(insert_fifo_q),
                              .insert_fifo_rden(insert_fifo_rden)
                              );

//*****************************************************************************
//  action_exe分析指令的结果
//******************************************************************************     
  fifo_wxx_dxx_s #(
      .PTR(5),
      .WORDS(32),
      .W_SIZE(76),
      .A_FULL(31)
    ) inst_actionexe_fifo (
      .clock         (clk),
      .rst_n         (rst_n),
      .fifo_wen      (action_en),
      .fifo_wdata    (action_fifout),
      .fifo_ren      (action_fifout_rden),
      .fifo_rdata    (action_fifout_q),
      .fifo_empty_rd (/*fifo_empty_rd*/),
      .almost_full   (/*almost_full*/)
    );

/***************************************************************/
//                     数据搬移至总线模块
/***************************************************************/      
fp_bus_ctrl U_fp_bus_ctrl(
                          .clk(clk),
                          .rst_n(rst_n),
                          //action_fifo的接口
                          .action_fifout_q(action_fifout_q),
                          .action_fifout_rden(action_fifout_rden),
                          // .action_fifout_empty(action_fifout_empty),
                          .trans_ready(trans_ready),   
                          //与RAM模块接口
                          .rd_rdy(rd_rdy),
                          .rd_data_i(fp_dpram_data),
                          .rd_en(fp_dpram_rden),
                          
                          //与总线的接口
                          .trans_start(trans_start),
			  .discard_start(discard_start),
                          .bus_data_o(bus_data_o),
                          .bus_data_val_o(bus_data_val_o),
                          .bus_data_end_o(bus_data_end_o),
                          .frame_len_bus(frame_len_bus),

                          //与捕获模块的接口
                          .capture_rdy(capture_rdy),
                          .capture_data_o(capture_data_o),
                          .capture_dval(capture_dval),
                          .cpt_en(cpt_en),
                          .cpt_frame_len(cpt_frame_len),

                          //帧信息信号
                          .frame_length_valid(fifo_wren),
                          .frame_length(frame_length),

                          //帧读取结束标志
                          .frame_rd_end(frame_rd_end)
                         );

endmodule
